//The MIT License
//
//Copyright (c) 2009 nodchip
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
package tv.dyndns.kishibe.client.bbs;

import java.util.Date;

import tv.dyndns.kishibe.client.Constant;
import tv.dyndns.kishibe.client.Sanitize;
import tv.dyndns.kishibe.client.Service;
import tv.dyndns.kishibe.client.UserData;
import tv.dyndns.kishibe.client.Utility;
import tv.dyndns.kishibe.client.packet.PacketBbsResponse;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

public class PanelThread extends VerticalPanel implements ClickHandler {
	private final int threadId;
	private final String title;
	private final VerticalPanel bodyPanel = new VerticalPanel();
	private final Button buttonAll = new Button("全部読む", this);
	private final Button buttonWrite = new Button("書き込む", this);
	private final PanelResponseForm responseForm = new PanelResponseForm(true);

	public PanelThread(int threadId, String title) {
		this.threadId = threadId;
		this.title = title;
		setEnabled(false);
		Service.Util.getInstance().getBbsResponses(threadId, Constant.BBS_INITIAL_RESPONSE_PER_THREAD, callbackGetBbsResponses);
	}

	private void setPanels() {
		final HTML titleHtml = new HTML(Sanitize.getInstance().html(title));
		titleHtml.addStyleDependentName("bbsThreadTitle");
		add(titleHtml);

		add(bodyPanel);

		{
			final HorizontalPanel panel = new HorizontalPanel();
			panel.add(buttonAll);
			panel.add(buttonWrite);
			add(panel);
		}

		add(responseForm);
	}

	private final AsyncCallback<PacketBbsResponse[]> callbackGetBbsResponses = new AsyncCallback<PacketBbsResponse[]>() {
		public void onSuccess(PacketBbsResponse[] result) {
			setResponses(result);
			setEnabled(true);
		}

		public void onFailure(Throwable caught) {
			caught.printStackTrace();
		}
	};

	private void setResponses(PacketBbsResponse[] responses) {
		bodyPanel.clear();

		if (!bodyPanel.isAttached()) {
			setPanels();
		}

		for (int i = 0; i < responses.length; ++i) {
			PacketBbsResponse response = responses[i];
			final VerticalPanel panel = new VerticalPanel();

			{
				String upper = "";
				switch (response.dispInfo) {
				case Constant.BBS_DISPLAY_INFO_ANONYMOUS:
					upper = response.id + ": " + Utility.getInstance().toDateFormat(new Date(response.postTime));
					break;
				case Constant.BBS_DISPLAY_INFO_NAME_ONLY:
					upper = response.id + ": " + Sanitize.getInstance().html(response.name) + " " + Utility.getInstance().toDateFormat(new Date(response.postTime));
					break;
				case Constant.BBS_DISPLAY_INFO_ALL_DATA:
					upper = response.id + ": " + Sanitize.getInstance().html(response.name) + Utility.getInstance().makeTrip(response.userCode, response.machineIp) + " " + Utility.getInstance().toDateFormat(new Date(response.postTime));
					break;
				}

				final HTML upperHtml = new HTML(upper);
				upperHtml.addStyleDependentName("bbsResponseHeader");
				panel.add(upperHtml);
			}

			final HTML bodyHtml = new HTML(response.body);
			bodyHtml.setWidth("800px");
			bodyHtml.addStyleDependentName("bbsResponseBody");
			panel.add(bodyHtml);
			bodyPanel.add(panel);
		}

		setEnabled(true);
	}

	private void showAll() {
		setEnabled(false);
		Service.Util.getInstance().getBbsResponses(threadId, Integer.MAX_VALUE, callbackGetBbsResponses);
	}

	private void write() {
		final PacketBbsResponse response = responseForm.getBbsResponse();
		if (response == null) {
			return;
		}

		setEnabled(false);

		response.threadId = threadId;

		final boolean age = responseForm.isAgeChecked();

		UserData.getInstance().setBbsDispInfo(response.dispInfo);
		UserData.getInstance().setBbsAge(age);

		Service.Util.getInstance().writeToBbs(response, age, callbackWriteToBbs);
	}

	private final AsyncCallback<Object> callbackWriteToBbs = new AsyncCallback<Object>() {
		public void onSuccess(Object result) {
			responseForm.clearForm();
			Service.Util.getInstance().getBbsResponses(threadId, Constant.BBS_INITIAL_RESPONSE_PER_THREAD, callbackGetBbsResponses);
		}

		public void onFailure(Throwable caught) {
			caught.printStackTrace();
		}
	};

	private void setEnabled(boolean enabled) {
		buttonAll.setEnabled(enabled);
		buttonWrite.setEnabled(enabled);
		responseForm.setEnabled(enabled);
	}

	@Override
	public void onClick(ClickEvent event) {
		final Object sender = event.getSource();
		if (sender == buttonAll) {
			showAll();
		} else if (sender == buttonWrite) {
			write();
		}
	}
}
